package Dao;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: Home-pc
 * Date: 2023-10-28
 * Time: 11:07
 */
//通过这个类将数据库建立连接和断开连接的逻辑进行封装
public class DBUtil {
    //进行连接前的准备工作，初始化数据库地址，用户名，密码
    //单例模式   只需要一个实例
    //volatile 禁止指令重排序
    private  static volatile DataSource dataSource=null;

    //提供一个方法获取datasource
    private static DataSource getDataSource(){
        if(dataSource==null){//此处if的作用在于避免频繁加锁；如果dataSource已经有值，再进行加锁，他会很快的解锁，但是这会导致频繁枷锁，因此一旦发现ataSource已经有值，就直接返回该值
            synchronized (DBUtil.class){//为了保证线程安全(多线程问题)，加锁
                if(dataSource==null){//第二个if判断是否为空，当a线程优先获得锁，执行到此处，b线程没竞争到锁会被阻塞在外面，a线程判断实例是否为空，为空则new实例，a线程释放锁之后，b线程拿到锁进来后先判断instance是否为null，此时可能因上一个线程导致此处不为null，则释放锁往下或者为null
                    dataSource=new MysqlDataSource();
                    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java_blog_system?useSSL=false&characterEncoding=utf8");
                    ((MysqlDataSource)dataSource).setUser("root");
                    //((MysqlDataSource)dataSource).setPassword("1111");
                    //云服务器端的mysql密码为空
                    ((MysqlDataSource)dataSource).setPassword("");
                }
            }
        }
        return dataSource;
    }

    //提供一个方法和数据库建立连接
    public static Connection getConnection(){
        try {
            return getDataSource().getConnection();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //提供一个方法和数据库断开连接 PreparedStatement statement用来执行SQL语句   ResultSet resultSet接收执行SQL语句后返回的结果
    public static void close(Connection connection, PreparedStatement statement, ResultSet resultSet){
        //将3个close放置到3个try中，即使前面的close出现问题，也不会影响后续close的执行
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
